package host.springboot.framework.autoconfigure.web;

import host.springboot.framework.autoconfigure.web.jackson.JacksonObjectMapperBuilder;
import host.springboot.framework.autoconfigure.web.properties.KsWebProperties;
import host.springboot.framework.autoconfigure.web.properties.children.KsJacksonProperties;
import host.springboot.framework.context.mvc.converter.*;
import host.springboot.framework.context.mvc.converter.factory.EnumConverterFactory;
import host.springboot.framework.core.constant.KrismileConstant;
import org.jspecify.annotations.NonNull;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.jackson.JacksonProperties;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 上下文自动配置类
 *
 * @author JiYinchuan
 * @since 1.0.0
 */
@AutoConfiguration(after = WebMvcAutoConfiguration.class)
@EnableConfigurationProperties({KsWebProperties.class, KsJacksonProperties.class})
public class KsWebAutoConfiguration {

    @Bean(KrismileConstant.KRISMILE_ABBREVIATION_LOWERCASE + "WebMvcConfigurer")
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addFormatters(@NonNull FormatterRegistry registry) {
                registry.addConverterFactory(new EnumConverterFactory());
                registry.addConverter(new DateConverter());
                registry.addConverter(new LocalDateTimeConverter());
                registry.addConverter(new LocalDateConverter());
                registry.addConverter(new LocalTimeConverter());
                registry.addConverter(new YearConverter());
                registry.addConverter(new YearMonthConverter());
                registry.addConverter(new MonthDayConverter());
                registry.addConverter(new ZonedDateTimeConverter());
                registry.addConverter(new OffsetDateTimeConverter());
                registry.addConverter(new OffsetTimeConverter());
            }
        };
    }

    /**
     * Jackson自动配置类
     *
     * @author JiYinchuan
     * @since 1.0.0
     */
    @Configuration(proxyBeanMethods = false)
    @ConditionalOnProperty(prefix = KsJacksonProperties.KEY, name = "enabled", havingValue = "true", matchIfMissing = true)
    static class JacksonConfiguration {

        @Bean(KrismileConstant.KRISMILE_ABBREVIATION_LOWERCASE + "Jackson2ObjectMapperBuilderCustomizer")
        public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer(
                ObjectProvider<JacksonProperties> jacksonProperties) {
            return new JacksonObjectMapperBuilder(jacksonProperties);
        }
    }
}
